package hyl.base.flow.chart;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import hyl.core.data.IMap;

/**
 * <p>
 * Description: 可遍历的节点,可以有n个输入和n个输出
 * </p>
 * 
 * @author: zdy
 * @date: 2018年9月16日 下午11:25:47
 * @copyright: 2018 da you zou Inc. All rights reserved.
 */
public class CNode extends ANode {

	public CNode() {
		super();
	}

	public CNode(String id) {
		super(id);
	}

	public CNode(String id, INode 父节点, IMount 添加事件) {
		super(id, 父节点, 添加事件);
	}

	public CNode(String id, INode 父节点, IMap<String, Object> 属性) {
		super(id, 父节点, 属性);
	}

	public CNode(String id, INode 父节点) {
		super(id, 父节点);
	}

	/**
	 * dimension=区位: 节点维度标识位 表示节点的关键特征 null表示无区 ，L左区，R右区 M中区
	 */

	protected List<INode> _前置节点集 = new ArrayList<>();
	// protected static final char idtype = 'A';// A: auto U: uuid
	// protected static final String prefix = "";
	// protected volatile static long no = 0; // 其实序号
	// 子节点
	protected List<INode> _后续节点集 = new ArrayList<>();

	public boolean hasParent() {
		return !_前置节点集.isEmpty();
	}

	public boolean hasChild() {
		return !_后续节点集.isEmpty();
	}

	/**
	 * @return the nodes
	 */
	public INode[] getParents() {
		// 必须这么搞,否则如果在外部添加子节点会破坏list结构
		return _前置节点集.toArray(new INode[0]);
	}

	/**
	 * @return the nodes
	 */
	public INode[] getChilds() {
		// 必须这么搞,否则如果在外部添加子节点会破坏list结构
		return _后续节点集.toArray(new INode[0]);
	}

	public INode[] getChilds(Map<String, String> 匹配属性) {
		List<INode> nds = new ArrayList<>();
		for (INode nd : _后续节点集) {
			boolean same = true;
			for (Entry<String, String> it : 匹配属性.entrySet()) {
				if (!nd.hasAttr(it.getKey(), it.getValue())) {
					same = false;
					break;
				}
			}
			if (same)
				nds.add(nd);
		}
		return nds.toArray(new INode[0]);// ??
	}

	/**
	 * 选择满足多个属性和值匹配的父节点集合
	 * 
	 * @param 匹配属性<属性,值>
	 * @return
	 */
	public INode[] getParents(Map<String, String> 匹配属性) {
		List<INode> nds = new ArrayList<>();
		for (INode nd : _前置节点集) {
			boolean same = true;
			for (Entry<String, String> it : 匹配属性.entrySet()) {
				if (!nd.hasAttr(it.getKey(), it.getValue())) {
					same = false;
					break;
				}
			}
			if (same)
				nds.add(nd);
		}
		return nds.toArray(new INode[0]);// ??
	}

	/**
	 * 选择满足属性和值匹配的父节点
	 * 
	 * @param 属性
	 * @param 值
	 * @return
	 */
	public INode getParent(String 属性, String 值) {
		for (INode nd : _前置节点集) {
			if (nd.hasAttr(属性, 值)) {
				return nd;
			}
		}
		return null;
	}

	public INode getChild(String 属性, String 值) {
		for (INode nd : _后续节点集) {
			if (nd.hasAttr(属性, 值)) {
				return nd;
			}
		}
		return null;
	}

	public void setParent(INode 节点) {
		_前置节点集.add(节点);
		callMountEvent(节点);
	}

	public boolean connParent(INode 节点) {
		if (节点 == null) {
			return false;
		}
		if (_前置节点集.contains(节点))
			return false;
		节点.setChild(this);
		setParent(节点);
		return true;
	}

	public void setChild(INode 节点) {
		if (_后续节点集.contains(节点))
			return;
		_后续节点集.add(节点);
	}

	public boolean connChild(INode 节点) {
		if (_后续节点集.contains(节点))
			return false;
		节点.setParent(this);
		_后续节点集.add(节点);
		return true;
	}

	public int getChildSize() {
		return _后续节点集.size();
	}

	public void removeParent(INode 前置节点) {
		if (前置节点 == null)
			return;
		if (_前置节点集.contains(前置节点)) {
			前置节点.removeChild(this);
			_前置节点集.remove(前置节点);
		}
	}

	public INode removeParent(int 前置节点) {
		INode nd = _前置节点集.get(前置节点);
		if (nd == null)
			return null;
		else {
			removeParent(nd);
			return nd;
		}
	}

	@Override
	public void removeChild(INode node) {
		if (node == null)
			return;
		if (_后续节点集.contains(node)) {
			node.removeParent(this);
			_后续节点集.remove(node);
		}
	}

	public INode removeChild(int 后续节点) {
		INode nd = _后续节点集.get(后续节点);
		if (nd == null)
			return null;
		else {
			removeChild(nd);
			return nd;
		}
	}

	@Override
	public INode getParent() {

		return _前置节点集.isEmpty() ? null : _前置节点集.get(0);
	}

	@Override
	public INode getChild() {

		return _后续节点集.isEmpty() ? null : _后续节点集.get(0);
	}

}
